﻿using Common;
using GomokuClient.Properties;
using GomokuCommon;
using System;
using System.Windows.Forms;

namespace GomokuClient {
    // 主窗口
    public partial class MainWindow: Form, RivalWindow.Callback {
        private readonly Game mGame;                // 游戏
        private readonly RivalWindow mRivalWindow;  // 对手列表窗口

        /**
         * 构造方法。
         */
        public MainWindow() {
            // 初始化控件
            this.InitializeComponent();

            // 设置状态栏
            LabelRivalName.Text = Resources.IDS_CURRENT_RIVAL;

            // 创建对手列表窗口
            mRivalWindow = new RivalWindow(this);

            // 创建游戏区域
            GameBoard gameBoard = new GameBoard(Controls, 0, MainMenu.Height, Const.GAME_BOARD_WIDTH, Const.GAME_BOARD_HEIGHT);
            gameBoard.MouseClick += new MouseEventHandler(GameBoard_MouseClick);

            // 创建游戏
            try {
                mGame = new Game(this, gameBoard.Drawer, gameBoard);
            } catch (Exception) {
                MessageBox.Show(Resources.IDS_NETWORK_ERROR, " ", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(0);
            }

            // 订阅事件
            mGame.OnGetLogonResult = new Game.ON_GET_LOGON_RESULT(OnGetLogonResult);
            mGame.OnGetFindUsersResult = new Game.ON_GET_FIND_USERS_RESULT(OnGetFindUsersResult);
            mGame.OnGetInviteRequest = new Game.ON_GET_INVITE_REQUEST(OnGetInviteRequest);
            mGame.OnGetInviteResult = new Game.ON_GET_INVITE_RESULT(OnGetInviteResult);
            mGame.OnGameStart = new Game.ON_GAME_START(OnGameStart);
            mGame.OnGameOver = new Game.ON_GAME_OVER(OnGameOver);
            mGame.OnRivalQuitGame = new Game.ON_RIVAL_QUIT_GAME(OnRivalQuitGame);
        }

        /**
         * 单击游戏区域事件的响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void GameBoard_MouseClick(object sender, MouseEventArgs e) {
            mGame.OnGameBoardClicked(e.Location.X, e.Location.Y);
        }

        /**
         * 窗口关闭中事件的响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void MainWindow_FormClosing(object sender, FormClosingEventArgs e) {
            mGame.Close();
        }

        /**
         * 窗口第一次显示事件的响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void MainWindow_Shown(object sender, EventArgs e) {
            // 登录
            string username = InputBox.GetStringValue("", Resources.IDS_INPUT_USERNAME);
            if (username != "") {
                mGame.Logon(username);
            } else {
                mGame.Close();
                Environment.Exit(0);
            }
        }

        /**
         * "认输"菜单项的单击响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void MenuItemDefeat_Click(object sender, EventArgs e) {
            mGame.Defeat();
        }

        /**
         * "寻找其它用户"菜单项的单击响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void MenuItemFindUsers_Click(object sender, EventArgs e) {
            mGame.FindUsers();
        }

        /**
         * "再来一局"菜单项的单击响应方法。
         * @param sender    事件发送者
         * @param e         事件相关信息
         */
        private void MenuItemRestart_Click(object sender, EventArgs e) {
            mGame.Restart();
        }

        /**
         * 游戏结束事件的响应方法。
         * @param reason    结束原因
         */
        private void OnGameOver(GameOverReason reason) {
            // 设置菜单项
            MenuItemFindUsers.Enabled = true;
            MenuItemDefeat.Enabled = false;
            MenuItemRestart.Enabled = true;

            // 显示提示信息
            switch (reason) {
                case GameOverReason.LOST:
                    MessageBox.Show(Resources.IDS_LOST, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
                case GameOverReason.RIVAL_ADMIT:
                    MessageBox.Show(Resources.IDS_RIVAL_ADMIT, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
                case GameOverReason.SELF_ADMIT:
                    MessageBox.Show(Resources.IDS_SELF_ADMIT, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
                case GameOverReason.WON:
                    MessageBox.Show(Resources.IDS_WON, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
            }
        }

        /**
         * 游戏开始事件的响应方法。
         * @param rivalName 对手的名字
         */
        private void OnGameStart(string rivalName) {
            // 隐藏对手列表窗口
            mRivalWindow.Hide();

            // 设置菜单项
            MenuItemFindUsers.Enabled = false;
            MenuItemDefeat.Enabled = true;
            MenuItemRestart.Enabled = false;

            // 显示对手的名字
            LabelRivalName.Text = Resources.IDS_CURRENT_RIVAL + rivalName;
        }

        /**
         * 得到寻找用户结果事件的响应方法。
         * @param result    结果
         */
        private void OnGetFindUsersResult(FindUsersResult result) {
            if (result.mUsernameList.Count > 0) {
                mRivalWindow.SetUsernameList(result.mUsernameList);
                mRivalWindow.Show();
            }
        }

        /**
         * 得到挑战请求事件的响应方法。
         * @param rivalName 对手的名字
         */
        private void OnGetInviteRequest(string rivalName) {
            string question = rivalName + Resources.IDS_INVITE;
            bool accept = MessageBox.Show(question, " ", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
            mGame.AcceptInvite(rivalName, accept);
        }

        /**
         * 得到挑战结果事件的响应方法。
         * @param rivalName 对手的名字
         * @param accept    接受挑战则为 true，否则为 false
         */
        private void OnGetInviteResult(string rivalName, bool accept) {
            string information = rivalName;
            if (accept) {
                information += Resources.IDS_ACCEPT;
            } else {
                information += Resources.IDS_REFUSE;
            }
            MessageBox.Show(information, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /**
         * 得到登录结果事件的响应方法。
         * @param succeeded 登录结果
         */
        private void OnGetLogonResult(bool succeeded) {
            if (succeeded) {
                MessageBox.Show(Resources.IDS_LOGON_SUCCEEDED, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
            } else {
                MessageBox.Show(Resources.IDS_LOGON_FAILED, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
                MainWindow_Shown(null, null);
            }
        }

        /**
         * 获取对手的名字事件的响应方法。
         * @param rivalName 对手的名字
         */
        public void OnGetRivalName(string rivalName) {
            mGame.Invite(rivalName);
        }

        /**
         * 对手退出游戏事件的响应方法。
         * @param escape    对手逃跑则为 true，正常退出则为 false
         * @param rivalName 对手的名字
         */
        private void OnRivalQuitGame(bool escape, string rivalName) {
            // 设置菜单项
            MenuItemFindUsers.Enabled = true;
            MenuItemDefeat.Enabled = false;
            MenuItemRestart.Enabled = false;

            // 设置状态栏
            LabelRivalName.Text = Resources.IDS_CURRENT_RIVAL;

            // 显示提示信息
            string text = rivalName;
            if (escape) {
                text += Resources.IDS_RIVAL_ESCAPE;
            } else {
                text += Resources.IDS_RIVAL_QUIT;
            }
            MessageBox.Show(text, " ", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
    }
}
